// 导入任务存储库，用于管理任务状态
import { useTaskStore } from '$/store'

// 导入实用函数，用于设备文件选择和发送，以及异步操作包装
import { selectAndSendFileToDevice } from '$/utils/device/index.js'
import { allSettledWrapper } from '$/utils/index.js'

// 导入 Element Plus 组件库，用于消息提示和确认对话框
import { ElMessage, ElMessageBox } from 'element-plus'

/**
 * 导出一个用于执行 Shell 操作的钩子函数
 * 该钩子提供了与设备进行 Shell 通信的功能
 */
export function useShellAction() {
  // 初始化任务存储库，用于管理任务状态
  const taskStore = useTaskStore()

  // 定义一个响应式 loading 状态，用于指示操作进行中
  const loading = ref(false)

  /**
   * 异步调用函数，根据传入的设备参数决定调用单个还是多个设备的 Shell 操作
   * @param {Array|Object} devices - 设备信息或设备列表
   * @param {Object} options - 附加选项，可能包含文件信息
   * @returns {Promise} - 操作结果的 Promise 对象
   */
  async function invoke(...args) {
    const [devices] = args

    // 根据设备参数是数组还是单个对象，决定调用多个还是单个设备的操作
    if (Array.isArray(devices)) {
      return multipleInvoke(...args)
    }

    return singleInvoke(...args)
  }

  /**
   * 单个设备的 Shell 操作函数
   * @param {Object} device - 设备信息
   * @param {Object} options - 附加选项，可能包含文件信息
   * @returns {Promise<boolean>} - 操作结果的 Promise 对象，失败时返回 false
   */
  async function singleInvoke(device, { files } = {}) {
    // 如果没有提供文件，调用文件选择和发送到设备的实用函数
    if (!files) {
      try {
        // 调用文件选择对话框，允许用户选择 .sh 文件
        files = await selectAndSendFileToDevice(device.id, {
          extensions: ['sh'],
          selectText: window.t('device.control.shell.select'), // 选择文件的提示文本
          loadingText: window.t('device.control.shell.push.loading'), // 加载中的提示文本
          successText: window.t('device.control.shell.push.success'), // 成功的提示文本
        })
      }
      catch (error) {
        // 如果文件选择或发送失败，显示警告消息并返回 false
        loading.value = false
        ElMessage.warning(error.message)
        return false
      }
    }

    // 设置 loading 状态为 true，表示操作正在进行
    loading.value = true

    // 获取第一个文件路径，构造 ADB 命令并发送到任务存储库
    const filePath = files[0]
    const command = `adb -s ${device.id} shell sh ${filePath}`

    // 发送命令到任务存储库，以便在终端中执行
    taskStore.emit('terminal', { command })

    // 设置 loading 状态为 false，表示操作完成
    loading.value = false
  }

  /**
   * 多个设备的 Shell 操作函数
   * @param {Array} devices - 设备列表
   * @param {Object} options - 附加选项，可能包含文件信息
   * @returns {Promise<boolean>} - 操作结果的 Promise 对象，失败时返回 false
   */
  async function multipleInvoke(devices, { files } = {}) {
    // 如果没有提供文件，调用文件选择对话框获取文件路径
    if (!files) {
      try {
        // 调用文件选择对话框，允许用户选择 .sh 文件
        files = await window.electron.ipcRenderer.invoke('show-open-dialog', {
          properties: ['openFile'], // 允许选择单个文件
          filters: [
            {
              name: window.t('device.control.shell.select'), // 过滤器名称
              extensions: ['sh'], // 允许的文件扩展名
            },
          ],
        })
      }
      catch (error) {
        // 如果文件选择失败，显示错误消息并返回 false
        if (error.message) {
          const message = error.message?.match(/Error: (.*)/)?.[1]
          ElMessage.warning(message || error.message)
        }
        return false
      }
    }

    // 设置 loading 状态为 true，表示操作正在进行
    loading.value = true

    // 显示加载消息，准备执行多个设备的 Shell 操作
    const closeLoading = ElMessage.loading(
      window.t('device.control.shell.push.loading'), // 加载中的提示文本
    ).close

    // 用于记录失败的文件操作信息
    const failFiles = []

    // 使用 allSettledWrapper 并行处理所有设备的文件发送和 Shell 执行操作
    await allSettledWrapper(devices, async (device) => {
      try {
        // 尝试将文件发送到设备
        const successFiles = await selectAndSendFileToDevice(device.id, {
          files,
          silent: true, // 静默模式，不显示提示
        })

        // 获取发送成功的文件路径
        const filePath = successFiles?.[0]

        if (filePath) {
          // 构造并执行 ADB 命令
          window.adbkit.deviceShell(device.id, `sh ${filePath}`)
        }
      } catch (e) {
        // 记录失败的文件操作信息
        console.warn(e.message)
        failFiles.push(e.message)
      }
    })

    // 如果有失败的操作，显示警告对话框并返回 false
    if (failFiles.length) {
      ElMessageBox.alert(
        `<div>${failFiles.map(text => `${text}<br/>`).join('')}</div>`, // 显示所有失败信息
        window.t('common.tips'), // 提示标题
        {
          type: 'warning', // 警告类型
          dangerouslyUseHTMLString: true, // 允许使用 HTML 字符串
        },
      )
      loading.value = false
      return false
    }

    // 关闭加载消息
    closeLoading()

    // 所有操作成功后，显示成功消息
    await ElMessage.success(window.t('device.control.shell.success'))

    // 设置 loading 状态为 false，表示操作完成
    loading.value = false
  }

  // 返回 Shell 操作的相关函数和 loading 状态
  return {
    invoke,
    loading,
    singleInvoke,
    multipleInvoke,
  }
}

// 默认导出 useShellAction 钩子函数
export default useShellAction
